﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExplorerPlus.DomainObjects;
using ExplorerPlus.PersistenceLayer;
using ExplorerPlus.PluginsInterface;
using ExplorerPlus.Utilities;

namespace ExplorerPlus
{
    public partial class ExplorerPlus : Form
    {
        IItemDetailViewPlugin itemDetailViewPlugin;
        Categories selectedCategory = Categories.Books;

        enum TreeViewLevels
        {
            Category = 0,
            Field = 1,
            Property = 2
        }

        public ExplorerPlus()
        {
            InitializeComponent();

            lstItems.DragEnter += new DragEventHandler(ExplorerPlus_DragEnter);
            lstItems.DragDrop += new DragEventHandler(ExplorerPlus_DragDrop);

            trvNavigation.DragEnter += new DragEventHandler(ExplorerPlus_DragEnter);
            trvNavigation.DragDrop += new DragEventHandler(ExplorerPlus_DragDrop);

            splitContainer1.DragEnter += new DragEventHandler(ExplorerPlus_DragEnter);
            splitContainer1.DragDrop += new DragEventHandler(ExplorerPlus_DragDrop);

            this.lstItems.DoubleClick += new System.EventHandler(this.lstItems_DoubleClick);

            this.notifyIcon1.Visible = Configuration.ConfigurationSettings.AppSettings.AlwaysShowTrayIcon;
        }

        private void ExplorerPlus_Load(object sender, EventArgs e)
        {
            Categories defaultCategory = Common.GetDefaultCategory();

            switch (defaultCategory)
            {
                case Categories.Books:
                    selectedCategory = Categories.Games;
                    tsbBooks_Click(sender, e);
                    break;
                case Categories.Games:
                    selectedCategory = Categories.Books;
                    tsbGames_Click(sender, e);
                    break;
                case Categories.Movies:
                    selectedCategory = Categories.Books;
                    tsbMovies_Click(sender, e);
                    break;
                case Categories.Music:
                    selectedCategory = Categories.Books;
                    tsbMusic_Click(sender, e);
                    break;
            }
        }

        #region TreeView Rendering

        private void LoadCategoryNodes()
        {
            this.SuspendLayout();
            trvNavigation.SuspendLayout();
            lstItems.SuspendLayout();

            trvNavigation.Nodes.Clear();
            lstItems.Items.Clear();

            TreeNode tn = new TreeNode();
            tn.Text = selectedCategory.ToString();
            tn.Tag = (int)selectedCategory;
            
            LoadCategoryFieldNodes(tn);
            
            trvNavigation.Nodes.Add(tn);
            trvNavigation.SelectedNode = trvNavigation.Nodes[0];
            trvNavigation.SelectedNode.Expand();

            trvNavigation.ResumeLayout(false);
            lstItems.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void LoadCategoryFieldNodes(TreeNode node)
        {
            List<FlyWeightItem> items = 
                PersistenceLayerFacade.GetFlyWeightCategoryFields((int)node.Tag);

            foreach (FlyWeightItem item in items)
            {
                TreeNode tn = new TreeNode();
                tn.Text = item.Name;
                tn.Tag = item.Id;
                node.Nodes.Add(tn);
                LoadCategoryFieldPropertyNodes(tn);
            }
        }

        private void LoadCategoryFieldPropertyNodes(TreeNode node)
        {
            List<FlyWeightItem> items =
                PersistenceLayerFacade.GetFlyWeightCategoryFieldItems((int)node.Parent.Tag, (int)node.Tag);

            foreach (FlyWeightItem item in items)
            {
                TreeNode tn = new TreeNode();
                tn.Text = item.Name;
                tn.Tag = item.Id;
                node.Nodes.Add(tn);
            }
        }

        private void trvNavigation_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            if (blnCancelRefresh)
                return;

            if (UnloadItemDetailViewPlugin(false))
            {
                this.trvNavigation.BeforeSelect -= new System.Windows.Forms.TreeViewCancelEventHandler(this.trvNavigation_BeforeSelect);
            }
        }

        #endregion

        #region ListView Rendering

        private void trvNavigation_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (blnCancelRefresh)
                return;

            //System.Diagnostics.Debug.Assert(trvNavigation.SelectedNode == null, "Treeview selected node is null");

            if (trvNavigation.SelectedNode != null)
            {
                this.Text = "Explorer Plus - " + trvNavigation.SelectedNode.Text;
                SetStatus("Ready");
                this.BeginInvoke(new MethodInvoker(LoadListView));
            }
        }

        private void lstItems_Enter(object sender, EventArgs e)
        {
            //System.Diagnostics.Debug.Assert(trvNavigation.SelectedNode == null, "Treeview selected node is null");

            if (trvNavigation.SelectedNode == null)
                return;

            switch ((TreeViewLevels)trvNavigation.SelectedNode.Level)
            {
                case TreeViewLevels.Category:
                case TreeViewLevels.Field:
                    tsbEdit.Enabled = false;
                    tsbDelete.Enabled = false;
                    break;
                case TreeViewLevels.Property:
                    tsbEdit.Enabled = true;
                    tsbDelete.Enabled = true;
                    break;
            }
        }

        private void LoadListView()
        {
            //System.Diagnostics.Debug.Assert(trvNavigation.SelectedNode == null, "Treeview selected node is null");

            if (trvNavigation.SelectedNode == null)
                return;

            switch ((TreeViewLevels)trvNavigation.SelectedNode.Level)
            {
                case TreeViewLevels.Category:
                case TreeViewLevels.Field:
                    LoadListMembers(trvNavigation.SelectedNode);
                    lstItems_Enter(this, null);
                    break;
                case TreeViewLevels.Property:
                    LoadListItems(trvNavigation.SelectedNode);
                    lstItems_Enter(this, null);
                    break;
            }
        }

        private void LoadListMembers(TreeNode tn)
        {
            this.SuspendLayout();
            lstItems.SuspendLayout();
            //lstItems.Items.Clear();
            //lstItems.Columns.Clear();
            lstItems.Clear();
            lstItems.Columns.Add("Name", lstItems.Width - 5);

            foreach (TreeNode node in tn.Nodes)
            {
                ListViewItem item = new ListViewItem();
                item.Text = node.Text;
                //item.Tag = node.Tag;
                item.ImageIndex = 1;
                lstItems.Items.Add(item);
            }

            SetItemsCount(lstItems.Items.Count);

            lstItems.ResumeLayout();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void LoadListItems(TreeNode tn)
        {
            this.SuspendLayout();
            lstItems.SuspendLayout();
            lstItems.Clear();
            lstItems.Columns.Add("Name", lstItems.Width - 5);

            List<FlyWeightItem> items =
                PersistenceLayerFacade.GetFlyWeightItems(
                    (int)tn.Parent.Parent.Tag,
                    (int)tn.Parent.Tag,
                    tn.Text);

            foreach (FlyWeightItem item in items)
            {
                ListViewItem lstItem = new ListViewItem();
                lstItem.Text = item.Name;
                lstItem.Tag = item.Id;
                lstItem.ImageIndex = 1;
                lstItems.Items.Add(lstItem);
            }

            SetItemsCount(lstItems.Items.Count);

            lstItems.ResumeLayout();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void lstItems_DoubleClick(object sender, EventArgs e)
        {
            if (lstItems.SelectedItems.Count > 0)
            {
                switch ((TreeViewLevels)trvNavigation.SelectedNode.Level)
                {
                    case TreeViewLevels.Category:
                    case TreeViewLevels.Field:
                        if (trvNavigation.SelectedNode == null)
                            return;

                        if (trvNavigation.SelectedNode.Nodes.Count > 0)
                        {
                            trvNavigation.SelectedNode.Expand();
                            foreach (TreeNode node in trvNavigation.SelectedNode.Nodes)
                            {
                                if (node.Text == lstItems.SelectedItems[0].Text)
                                {
                                    trvNavigation.SelectedNode = node;
                                    lstItems.Focus();
                                    break;
                                }
                            }
                        }
                        break;
                    case TreeViewLevels.Property:
                        this.Cursor = Cursors.WaitCursor;

                        Item item = PersistenceLayerFacade.GetItem(
                            (int)this.selectedCategory, 
                            (int)lstItems.SelectedItems[0].Tag);

                        this.Text = "Explorer Plus - Edit - " + item.ItemName;

                        LoadItemDetailViewPlugin(item);

                        this.Cursor = Cursors.Default;

                        break;
                }
            }
        }

        private void lstItems_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Enter:
                    this.lstItems_DoubleClick(sender, null);
                    e.Handled = true;
                    break;

                case Keys.Back:
                    switch ((TreeViewLevels)trvNavigation.SelectedNode.Level)
                    {
                        case TreeViewLevels.Category:
                            // do nothing
                            break;
                        case TreeViewLevels.Field:
                        case TreeViewLevels.Property:
                            if (trvNavigation.SelectedNode != null)
                            {
                                trvNavigation.SelectedNode = trvNavigation.SelectedNode.Parent;
                                lstItems.Focus();
                                e.Handled = true;
                            }
                            break;
                    }
                    break;

                case Keys.Space:
                    if (lstItems.Items.Count > 0)// && lstItems.SelectedItems.Count == 0)
                    {
                        if (lstItems.FocusedItem != null)
                        {
                            lstItems.FocusedItem.Selected = true;// !lstItems.FocusedItem.Selected;
                        }
                        else
                        {
                            lstItems.Items[0].Selected = true;
                            lstItems.Items[0].Focused = true;
                        }
                        e.Handled = true;
                    }
                    
                    break;
            }
        }

        #endregion

        #region Toolstrip handling

        private void tsbBooks_Click(object sender, EventArgs e)
        {
            SwitchCategory(tsbBooks, mnuViewBooks, Categories.Books);
        }

        private void tsbMovies_Click(object sender, EventArgs e)
        {
            SwitchCategory(tsbMovies, mnuViewMovies, Categories.Movies);
        }

        private void tsbMusic_Click(object sender, EventArgs e)
        {
            SwitchCategory(tsbMusic, mnuViewMusic, Categories.Music);
        }

        private void tsbGames_Click(object sender, EventArgs e)
        {
            SwitchCategory(tsbGames, mnuViewGames, Categories.Games);
        }

        private void SwitchCategory(ToolStripButton tsbClicked, ToolStripMenuItem mnuClicked, Categories checkedCategory)
        {
            this.Cursor = Cursors.WaitCursor;

            if (this.selectedCategory == checkedCategory)
            {
                tsbClicked.Checked = true;
                return;
            }

            if (!UnloadItemDetailViewPlugin(false))
            {
                return;
            }

            tsbBooks.Checked = false;
            tsbMovies.Checked = false;
            tsbMusic.Checked = false;
            tsbGames.Checked = false;
            mnuViewBooks.Checked = false;
            mnuViewMovies.Checked = false;
            mnuViewMusic.Checked = false;
            mnuViewGames.Checked = false;
            tsbClicked.Checked = true;
            mnuClicked.Checked = true;
            tsbEdit.Enabled = false;
            tsbSave.Enabled = false;
            tsbDelete.Enabled = false;
            tsbClose.Enabled = false;

            this.selectedCategory = checkedCategory;

            this.BeginInvoke(new MethodInvoker(LoadCategoryNodes));

            SetStatus("Ready");

            this.notifyIcon1.Text = "Explorer Plus - " + selectedCategory.ToString();

            this.Cursor = Cursors.Default;
        }

        private void tsbNew_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            if (this.itemDetailViewPlugin != null
                && this.Text != "Explorer Plus - New " + selectedCategory.ToString())
            {
                if (!UnloadItemDetailViewPlugin(false))
                {
                    this.Cursor = Cursors.Default;
                    return;
                }
            }

            if (this.itemDetailViewPlugin == null)
            {
                this.Text = "Explorer Plus - New " + selectedCategory.ToString();

                Item item = new Item((int)selectedCategory);

                LoadItemDetailViewPlugin(item);
            }

            this.Cursor = Cursors.Default;
        }

        private void tsbEdit_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            if (this.itemDetailViewPlugin == null)
            {
                if (trvNavigation.SelectedNode == null)
                    return;

                if (trvNavigation.SelectedNode.Level == (int)TreeViewLevels.Property)
                {
                    if (lstItems.SelectedItems.Count > 0)
                    {
                        lstItems_DoubleClick(sender, e);
                    }
                }
            }

            this.Cursor = Cursors.Default;
        }

        bool blnCancelRefresh = false;
        private void tsbSave_Click(object sender, EventArgs e)
        {
            //TODO: Add logic to save item
            if (itemDetailViewPlugin != null)
            {
                try
                {
                    this.Cursor = Cursors.WaitCursor;

                    if (itemDetailViewPlugin.Validate())
                    {
                        Item currentItem = itemDetailViewPlugin.Store();
                        if (PersistenceLayerFacade.SaveItem(currentItem))
                        {
                            SetStatus("Item Saved");
                            blnCancelRefresh = true;
                            //this.trvNavigation.BeforeSelect -= new System.Windows.Forms.TreeViewCancelEventHandler(trvNavigation_BeforeSelect);
                            //this.trvNavigation.AfterSelect -= new TreeViewEventHandler(trvNavigation_AfterSelect);

                            this.splitContainer1.Panel1.SuspendLayout();
                            this.splitContainer1.SuspendLayout();
                            this.SuspendLayout();

                            for (int i = 0; i < trvNavigation.Nodes[0].Nodes.Count; i++)
                            {
                                trvNavigation.Nodes[0].Nodes[i].Nodes.Clear();
                                LoadCategoryFieldPropertyNodes(trvNavigation.Nodes[0].Nodes[i]);
                            }

                            //this.trvNavigation.AfterSelect += new TreeViewEventHandler(trvNavigation_AfterSelect);
                            //this.trvNavigation.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(trvNavigation_BeforeSelect);
                            blnCancelRefresh = false;

                            this.Text = "Explorer Plus - Edit - " + currentItem.ItemName;

                            this.splitContainer1.Panel1.ResumeLayout(false);
                            this.splitContainer1.ResumeLayout(false);
                            this.ResumeLayout(false);
                            this.PerformLayout();
                        }
                    }
                }
                finally
                {
                    this.Cursor = Cursors.Default;
                }
            }
        }

        private void tsbDelete_Click(object sender, EventArgs e)
        {
            if (itemDetailViewPlugin != null)
            {
                // TODO: Add logic to delete opened item
                Item currentItem = itemDetailViewPlugin.GetItem();
                if (currentItem.ItemId != -1)
                {
                    if (!ConfirmItemDeletion())
                    {
                        return;
                    }

                    if (UnloadItemDetailViewPlugin(true))
                    {
                        PersistenceLayerFacade.DeleteItem((int)selectedCategory, currentItem.ItemId);
                    }

                    RefreshListAfterDelete();
                }
                else
                {
                    UnloadItemDetailViewPlugin(true);
                }
            }
            else if (trvNavigation.SelectedNode != null && trvNavigation.SelectedNode.Level == (int)TreeViewLevels.Property)
            {
                if (lstItems.SelectedItems.Count > 0)
                {
                    //TODO: Add logic to delete items
                    if (!ConfirmItemDeletion())
                    {
                        return;
                    }

                    foreach (ListViewItem item in lstItems.SelectedItems)
                    {
                        PersistenceLayerFacade.DeleteItem((int)selectedCategory, (int)item.Tag);
                    }

                    RefreshListAfterDelete();
                }
            }
        }

        private bool ConfirmItemDeletion()
        {
            if (Configuration.ConfigurationSettings.AppSettings.ConfirmWhenDeletingItems)
            {
                return (MessageBox.Show("Are you sure you want to delete the selected item(s)?",
                    "Confirm item(s) Delete", MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes);
            }

            return true;
        }

        private void RefreshListAfterDelete()
        {
            SetStatus("Item(s) Deleted");
            blnCancelRefresh = true;
            //this.trvNavigation.BeforeSelect -= new System.Windows.Forms.TreeViewCancelEventHandler(trvNavigation_BeforeSelect);
            //this.trvNavigation.AfterSelect -= new TreeViewEventHandler(trvNavigation_AfterSelect);

            this.splitContainer1.Panel1.SuspendLayout();
            this.splitContainer1.SuspendLayout();
            this.SuspendLayout();

            for (int i = 0; i < trvNavigation.Nodes[0].Nodes.Count; i++)
            {
                trvNavigation.Nodes[0].Nodes[i].Nodes.Clear();
                LoadCategoryFieldPropertyNodes(trvNavigation.Nodes[0].Nodes[i]);
            }

            //this.trvNavigation.AfterSelect += new TreeViewEventHandler(trvNavigation_AfterSelect);
            //this.trvNavigation.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(trvNavigation_BeforeSelect);
            blnCancelRefresh = false;

            this.splitContainer1.Panel1.ResumeLayout(false);
            this.splitContainer1.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

            LoadListView();
        }

        private void tsbClose_Click(object sender, EventArgs e)
        {
            UnloadItemDetailViewPlugin(false);
        }

        private void tsbImport_Click(object sender, EventArgs e)
        {

        }

        private void tsbSearchOnline_Click(object sender, EventArgs e)
        {
            if (Configuration.ConfigurationSettings.AppSettings.AdvancedSearch)
            {
                using (SearchOnlineAdvanced form = new SearchOnlineAdvanced(this.selectedCategory))
                {
                    if (itemDetailViewPlugin != null)
                    {
                        form.SetKeyword(itemDetailViewPlugin.GetItem().ItemName);
                    }
                    if (form.ShowDialog() == DialogResult.OK)
                    {
                        if (itemDetailViewPlugin == null)
                        {
                            this.Text = "Explorer Plus - New " + selectedCategory.ToString();
                            LoadItemDetailViewPlugin(form.item);
                            itemDetailViewPlugin.HasChanges = true;
                        }
                        else
                        {
                            Item item = itemDetailViewPlugin.GetItem();
                            form.item.ItemId = item.ItemId;
                            form.item.FilePath = item.FilePath;
                            itemDetailViewPlugin.Initialize(form.item);
                        }
                    }
                }
            }
            else
            {
                using (SearchOnline form = new SearchOnline(this.selectedCategory))
                {
                    if (itemDetailViewPlugin != null)
                    {
                        form.SetKeyword(itemDetailViewPlugin.GetItem().ItemName);
                    }
                    if (form.ShowDialog() == DialogResult.OK)
                    {
                        if (itemDetailViewPlugin == null)
                        {
                            this.Text = "Explorer Plus - New " + selectedCategory.ToString();
                            LoadItemDetailViewPlugin(form.item);
                            itemDetailViewPlugin.HasChanges = true;
                        }
                        else
                        {
                            Item item = itemDetailViewPlugin.GetItem();
                            form.item.ItemId = item.ItemId;
                            form.item.FilePath = item.FilePath;
                            itemDetailViewPlugin.Initialize(form.item);
                        }
                    }
                }
            }
        }

        private void tsbRefresh_Click(object sender, EventArgs e)
        {
            PersistenceLayerFacade.ClearCache();

            switch (selectedCategory)
            {
                case Categories.Books:
                    selectedCategory = Categories.Games;
                    tsbBooks_Click(this, null);
                    break;
                case Categories.Games:
                    selectedCategory = Categories.Books;
                    tsbGames_Click(this, null);
                    break;
                case Categories.Movies:
                    selectedCategory = Categories.Books;
                    tsbMovies_Click(this, null);
                    break;
                case Categories.Music:
                    selectedCategory = Categories.Books;
                    tsbMusic_Click(this, null);
                    break;
            }
        }

        private void tsbSettings_Click(object sender, EventArgs e)
        {
            using (Preferences pref = new Preferences())
            {
                if (pref.ShowDialog(this) == DialogResult.OK)
                {
                    this.notifyIcon1.Visible = 
                        Configuration.ConfigurationSettings.AppSettings.AlwaysShowTrayIcon;
                }
            }
        }

        private void tsbHelp_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            try
            {
                System.Diagnostics.Process.Start(
                    Application.StartupPath + "\\Help\\index.htm");
            }
            catch
            {
            }
            this.Cursor = Cursors.Default;
        }

        #endregion

        #region Menu handling

        private void mnuFileNew_Click(object sender, EventArgs e)
        {
            tsbNew_Click(sender, e);
        }

        private void mnuFileEdit_Click(object sender, EventArgs e)
        {
            tsbEdit_Click(sender, e);
        }

        private void mnuFileDelete_Click(object sender, EventArgs e)
        {
            tsbDelete_Click(sender, e);
        }

        bool blnClose = false;
        private void mnuFileClose_Click(object sender, EventArgs e)
        {
            blnClose = true;
            Application.Exit();
        }

        private void mnuEditFind_Click(object sender, EventArgs e)
        {
            using (Find form = new Find())
            {
                form.ShowDialog();
            }
        }

        private void mnuEditSearchOnline_Click(object sender, EventArgs e)
        {
            tsbSearchOnline_Click(sender, e);
        }

        private void mnuViewBooks_Click(object sender, EventArgs e)
        {
            tsbBooks_Click(sender, e);
        }

        private void mnuViewMovies_Click(object sender, EventArgs e)
        {
            tsbMovies_Click(sender, e);
        }

        private void mnuViewMusic_Click(object sender, EventArgs e)
        {
            tsbMusic_Click(sender, e);
        }

        private void mnuViewGames_Click(object sender, EventArgs e)
        {
            tsbGames_Click(sender, e);
        }

        private void mnuViewRefresh_Click(object sender, EventArgs e)
        {
            tsbRefresh_Click(sender, e);
        }

        private void mnuToolsFileImport_Click(object sender, EventArgs e)
        {
            if (System.IO.File.Exists(Application.StartupPath + "\\ExplorerPlus.Tools.exe"))
            {
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo.Arguments = "-f";
                proc.StartInfo.FileName = 
                    Application.StartupPath + "\\ExplorerPlus.Tools.exe";
                proc.Start();
            }
        }

        private void mnuToolsWebImport_Click(object sender, EventArgs e)
        {
            if (System.IO.File.Exists(Application.StartupPath + "\\ExplorerPlus.Tools.exe"))
            {
                System.Diagnostics.Process.Start(
                    Application.StartupPath + "\\ExplorerPlus.Tools.exe");
            }
        }

        private void mnuToolsOptions_Click(object sender, EventArgs e)
        {
            tsbSettings_Click(sender, e);
        }

        private void mnuHelpHelp_Click(object sender, EventArgs e)
        {
            tsbHelp_Click(sender, e);
        }

        private void mnuHelpAbout_Click(object sender, EventArgs e)
        {
            using (About frmAbout = new About())
            {
                frmAbout.ShowDialog();
            }
        }

        private void SetItemsCount(int count)
        {
            lblItemsCount.Text = string.Format("{0} Item(s)", count);
        }

        private void SetStatus(string text)
        {
            lblStatus.Text = text;
        }

        #endregion

        #region Drag Drop handling

        private void ExplorerPlus_DragEnter(object sender, DragEventArgs e)
        {
            // If the data is a file, display the copy cursor.
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void ExplorerPlus_DragDrop(object sender, DragEventArgs e)
        {
            // Handle FileDrop data.
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Assign the file names to a string array, in 
                // case the user has selected multiple files.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

                if (itemDetailViewPlugin == null)
                {
                    tsbNew_Click(sender, null);
                }

                if (itemDetailViewPlugin != null)
                {
                    itemDetailViewPlugin.DragDropFile(files);
                }
            }
        }

        #endregion

        #region Plugins Management

        private void LoadItemDetailViewPlugin(Item item)
        {
            Plugin assembly = 
                PersistenceLayerFacade.GetCategoryPlugins((int)selectedCategory);
            object plugin =
                PluginManager.CreateInstance("IItemDetailViewPlugin", Application.StartupPath + "\\" + assembly.ItemDetailViewPlugin);

            if (plugin != null)
            {
                itemDetailViewPlugin = (IItemDetailViewPlugin)plugin;
                itemDetailViewPlugin.Initialize(item);
                itemDetailViewPlugin.ItemDetailView.Height = splitContainer1.Panel2.Height;
                itemDetailViewPlugin.ItemDetailView.Width = splitContainer1.Panel2.Width;

                this.splitContainer1.Panel2.SuspendLayout();
                this.splitContainer1.SuspendLayout();
                this.SuspendLayout();

                splitContainer1.Panel2.Controls.Clear();
                splitContainer1.Panel2.Controls.Add(itemDetailViewPlugin.ItemDetailView);
                splitContainer1.Panel2.Controls[0].Dock = DockStyle.Fill;

                tsbEdit.Enabled = true;
                tsbSave.Enabled = true;
                tsbDelete.Enabled = true;
                tsbClose.Enabled = true;

                this.splitContainer1.Panel2.ResumeLayout(false);
                this.splitContainer1.ResumeLayout(false);
                this.ResumeLayout(false);
                this.PerformLayout();

                itemDetailViewPlugin.ItemDetailView.Focus();

                this.trvNavigation.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.trvNavigation_BeforeSelect);
            }
            else
            {
                MessageBox.Show("Plugin is not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private bool UnloadItemDetailViewPlugin(bool forceClose)
        {
            if (itemDetailViewPlugin != null || blnCancelRefresh)
            {
                //if (Configuration.ConfigurationSettings.AppSettings.AutoSave && itemDetailViewPlugin.HasChanges)
                //{
                //    tsbSave_Click(null, null);
                //}

                if (!forceClose)
                {
                    if (Configuration.ConfigurationSettings.AppSettings.ConfirmForChangesMade)
                    {
                        if (itemDetailViewPlugin.HasChanges)
                        {
                            if (DialogResult.No ==
                                        MessageBox.Show("Some changes are currently pending. Do you want to proceed and ignore these changes?",
                                        "Pending Changes",
                                        MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Warning,
                                        MessageBoxDefaultButton.Button1))
                            {
                                return false; ;
                            }
                        }
                    }
                }

                this.SuspendLayout();
                this.splitContainer1.Panel2.SuspendLayout();

                tsbEdit.Enabled = false;
                tsbSave.Enabled = false;
                tsbDelete.Enabled = false;
                tsbClose.Enabled = false;

                splitContainer1.Panel2.Controls.Clear();
                splitContainer1.Panel2.Controls.Add(lstItems);

                if (trvNavigation.Nodes.Count > 0)
                {
                    if (trvNavigation.SelectedNode != null)
                    {
                        this.Text = "Explorer Plus - " + trvNavigation.SelectedNode.Text;
                    }
                    else
                    {
                        this.Text = "Explorer Plus";
                    }
                }

                if (itemDetailViewPlugin != null)
                {
                    itemDetailViewPlugin.Dispose();
                    itemDetailViewPlugin = null;
                }

                this.trvNavigation.BeforeSelect -= new System.Windows.Forms.TreeViewCancelEventHandler(this.trvNavigation_BeforeSelect);

                lstItems.Focus();
                if (lstItems.SelectedItems.Count > 0)
                {
                    lstItems.SelectedItems[0].Focused = true;
                }

                this.splitContainer1.Panel2.ResumeLayout(false);
                this.ResumeLayout(false);
                this.PerformLayout();
            }

            return true;
        }

        #endregion

        #region Form handling

        private void ExplorerPlus_Resize(object sender, EventArgs e)
        {
            this.lblStatus.Width = this.Width - lblItemsCount.Width - 23;
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            const int WM_KEYDOWN = 0x100;
            const int WM_SYSKEYDOWN = 0x104;

            if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
            {
                switch (keyData)
                {
                    case Keys.Control | Keys.N:
                        tsbNew_Click(this, null);
                        return true;

                    case Keys.F2:
                        tsbEdit_Click(this, null);
                        return true;

                    case Keys.Control | Keys.S:
                        tsbSave_Click(this, null);
                        return true;

                    case Keys.Control | Keys.Shift | Keys.F:
                        tsbSearchOnline_Click(this, null);
                        return true;

                    case Keys.F1:
                        tsbHelp_Click(this, null);
                        return true;

                    case Keys.Control | Keys.P:
                        tsbSettings_Click(this, null);
                        return true;

                    case Keys.Control | Keys.W:
                        tsbClose_Click(this, null);
                        return true;

                    case Keys.F5:
                        tsbRefresh_Click(this, null);
                        return true;

                    case Keys.Delete:
                    case Keys.Shift | Keys.Delete:
                        if (itemDetailViewPlugin == null)
                        {
                            tsbDelete_Click(this, null);
                            return true;
                        }
                        break;

                    case Keys.Control | Keys.D1:
                        tsbBooks_Click(this, null);
                        return true;

                    case Keys.Control | Keys.D2:
                        tsbMovies_Click(this, null);
                        return true;

                    case Keys.Control | Keys.D3:
                        tsbMusic_Click(this, null);
                        return true;

                    case Keys.Control | Keys.D4:
                        tsbGames_Click(this, null);
                        return true;

                    case Keys.Control | Keys.A:
                        if (lstItems.Focused && lstItems.Items.Count > 0)
                        {
                            foreach (ListViewItem lvItem in lstItems.Items)
                            {
                                lvItem.Selected = true;
                            }
                            return true;
                        }
                        break;
                }
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void ExplorerPlus_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                if (Configuration.ConfigurationSettings.AppSettings.MinimizeToTray)
                {
                    this.Hide();
                    this.notifyIcon1.Visible = true;
                }
            }
        }

        private void ExplorerPlus_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Configuration.ConfigurationSettings.AppSettings.CloseToTray && !blnClose)
            {
                e.Cancel = true;
                this.Hide();
                this.notifyIcon1.Visible = true;
            }
            else
            {
                this.notifyIcon1.Visible = false;
            }
        }

        private void notifyIcon1_Click(object sender, EventArgs e)
        {
            if (Configuration.ConfigurationSettings.AppSettings.SingleClickOnTrayToOpen)
            {
                notifyIcon1_DoubleClick(sender, e);
            }
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            // Show the form when the user double clicks on the notify icon.
            this.notifyIcon1.Visible = Configuration.ConfigurationSettings.AppSettings.AlwaysShowTrayIcon;

            // Activate the form.
            this.Show();
            // Set the WindowState to maximized if the form is minimized.
            if (this.WindowState == FormWindowState.Minimized)
                this.WindowState = FormWindowState.Maximized;

            this.Activate();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            mnuFileClose_Click(sender, e);
        }

        #endregion
    }
}
